/***********************************************************
 *功能：采集空气数据通过GPRS发送到服务端 
 *作者：Oliver
 *日期：2018.6.8
 *
**********************GPRS模块************************************/
#include <TimerOne.h>     
#define DebugSerial Serial
#define GprsSerail Serial3   
#define Success 1U
#define Failure 0U
int L = 13;  
unsigned long  Time_Cont = 0;       //定时器计数器
const unsigned int gprsRxBufferLength = 1000;
char gprsRxBuffer[gprsRxBufferLength];
unsigned int gprsBufferCount = 0;
char phoneNumber[] = "18790256422";   //替换成需要被拨打电话的号码
char msg[] = "AYGXY IOT";   //短信内容
const char TCPServer[] = "www.qiongyi666.xyz";   //TCP服务器地址
const char Port[] = "80";            //端口
const char Cmd[] = "POST /pollute/index.php";
char send_buffer[100] = {0};
char send_buf[100] = {0};
/**********************DHT11*********************************/
#include <dht11.h>
#define DHT11PIN 8
dht11 DHT11;
int Temperature;
int Humidity;
/**********************OLED*********************************/ 
#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
void SendLcd() {
   u8g.firstPage();
  do {
     u8g.setFont(u8g_font_timB12);
     for(int j = 0;j<=128;j++){
      u8g.drawStr( j, 19, ".");
    }
     for(int k = 19;k<=64;k++){
      u8g.drawStr( 0, k, ".");
    }
    for(int m = 19;m<=64;m++){
      u8g.drawStr( 125, m, ".");
    }
    u8g.drawStr( 8, 31, "AYGXY-TXGC");
    u8g.drawStr( 27, 45, "FlightIOT");
    u8g.drawStr( 40, 60, "Data");
     for(int i = 0;i<=128;i++){
      u8g.drawStr( i, 64, ".");
    } 
  } while ( u8g.nextPage() );
}
/************************CO2Data************************************/
#define         MG_PIN                       (A0)      
#define         DC_GAIN                      (8.5)   
#define         READ_SAMPLE_INTERVAL         (50)     
#define         READ_SAMPLE_TIMES            (5)      
#define         ZERO_POINT_VOLTAGE           (0.220) 
#define         REACTION_VOLTGAE             (0.030)  
float           CO2Curve[3]  =  {2.602,ZERO_POINT_VOLTAGE,(REACTION_VOLTGAE/(2.602-3))};
int percentage;
float volts;
/************************PMData*****************************************/
#include <Arduino.h>
#define LENG 31    
unsigned char buf[LENG];
int PM01Value=0;          
int PM2_5Value=0;          
int PM10Value=0; 
int smoke = 0;
/***************************复位****************************************/
void(* resetFunc) (void) = 0;
/***************************数据发送****************************************/
void sendToServer(){
      DHTData();
      CO2Data();
      PMData();
      Smoke();
      strcat(send_buf, Cmd);
      strcat(send_buf, "?t=");
      sprintf(send_buffer,"%d",Temperature);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&h=");
      sprintf(send_buffer,"%d",Humidity);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&pm2_5=");
      sprintf(send_buffer,"%d",PM2_5Value);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&pm1=");
      sprintf(send_buffer,"%d",PM01Value);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&pm10=");
      sprintf(send_buffer,"%d",PM10Value);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&co2=");
      sprintf(send_buffer,"%d",percentage);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "&s=");
      sprintf(send_buffer,"%d",smoke);
      strcat(send_buf,send_buffer);
      strcat(send_buf, "\r\n");
      strcat(send_buf, "Host:");
      strcat(send_buf, TCPServer);
      strcat(send_buf, "\r\n");       
}
/*******************************************************************/
void setup() {
  pinMode(L, OUTPUT);
  digitalWrite(L, LOW);
  DebugSerial.begin(9600);
  GprsSerail.begin(9600);
  Serial2.begin(9600);    
  Timer1.initialize(1000);
  Timer1.attachInterrupt(Timer1_handler);
}
/*******************************************************************/
void loop() {
  SendLcd();
  Gprs_Data();
  delay(10000);
  
}
/*************************GPRS数据循环发送******************************************/
void Gprs_Data() {
    initGprs();
    DebugSerial.println("\r\nsetup end!");
    clrGprsRxBuffer();
    memset(send_buf, 0, 100);    //清空
    memset(send_buffer, 0, 100);    //清空
    strcpy(send_buf, "AT+CIPSTART=\"TCP\",\"");
    strcat(send_buf, TCPServer);
    strcat(send_buf, "\",\"");
    strcat(send_buf, Port);
    strcat(send_buf, "\"\r\n");
    if (sendCommand(send_buf, "CONNECT", 10000, 5) == Success);
    else errorLog(8);
    if (sendCommand("AT+CIPSEND\r\n", ">", 3000, 5) == Success);
    else errorLog(9);
    memset(send_buf, 0, 100);    //清空
    memset(send_buffer, 0, 100);    //清空
    sendToServer();

   u8g.firstPage();
  do {
     u8g.setFont(u8g_font_timB12);
     u8g.drawStr( 3, 30, "SUCCEED");
    u8g.setFont(u8g_font_timB14);
    u8g.drawStr( 0, 15, "FlightIOT");
    u8g.setFont(u8g_font_timB12);
    u8g.drawStr( 74, 46, "Dsta");  
  } while ( u8g.nextPage() );
    
    if (sendCommand(send_buf, send_buf, 3000, 1) == Success);
    else errorLog(10);
    delay(1000);
    memset(send_buf, 0, 100);    //清空
    memset(send_buffer, 0, 100);    //清空
    send_buf[0] = 0x1a; 
    if (sendCommand(send_buf, send_buf, 5000, 5) == Success);
    else errorLog(11);
    delay(500);
    if (sendCommand("AT+CIPCLOSE=1\r\n", "OK\r\n", 5000, 10) == Success);
    else errorLog(12);
    delay(100);
    if (sendCommand("AT+CIPSHUT\r\n", "OK\r\n", 5000, 10) == Success);
    else errorLog(13);
    delay(1000);  
}
/***************************初始化GSM****************************************/
void initGprs()
{
  if (sendCommand("AT\r\n", "OK\r\n", 100, 10) == Success);
  else errorLog(2);
  delay(10);
  if (sendCommandReceive2Keyword("AT+CPIN?\r\n", "READY", "OK\r\n", 3000, 10) == Success);
  else errorLog(3);
  delay(10);
  if (sendCommand("AT+CGCLASS=\"B\"\r\n", "OK\r\n", 1000, 10) == Success);
  else errorLog(4);
  delay(10);
  if (sendCommand("AT+CGDCONT=1,\"IP\",\"CMNET\"\r\n", "OK\r\n", 5000, 2) == Success);
  else errorLog(5);
  delay(10);
  if (sendCommand("AT+CGATT=1\r\n","OK\r\n", 1000, 10) == Success);
  else errorLog(6);
  delay(10);
}
void errorLog(int num)
{
  DebugSerial.print("ERROR");
  DebugSerial.println(num);
  while (1)
  {
    if (sendCommand("AT\r\n", "OK\r\n", 100, 10) == Success)
    {
      DebugSerial.print("\r\nRESET!!!!!!\r\n");
      resetFunc();
    }
  }
}
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry)
{
  clrGprsRxBuffer();
  for (unsigned char n = 0; n < Retry; n++)
  {
    DebugSerial.print("\r\n---------send AT Command:---------\r\n");
    DebugSerial.write(Command);
    GprsSerail.write(Command);
    Time_Cont = 0;
    while (Time_Cont < Timeout)
    {
      gprsReadBuffer();
      if (strstr(gprsRxBuffer, Response) != NULL)
      {
        DebugSerial.print("\r\n==========receive AT Command:==========\r\n");
        DebugSerial.print(gprsRxBuffer); //输出接收到的信息
        clrGprsRxBuffer();
        return Success;
      }
    }
    Time_Cont = 0;
  }
  DebugSerial.print("\r\n==========receive AT Command:==========\r\n");
  DebugSerial.print(gprsRxBuffer);//输出接收到的信息
  clrGprsRxBuffer();
  return Failure;
}
unsigned int sendCommandReceive2Keyword(char *Command, char *Response, char *Response2, unsigned long Timeout, unsigned char Retry)
{
  clrGprsRxBuffer();
  for (unsigned char n = 0; n < Retry; n++)
  {
    DebugSerial.print("\r\n---------send AT Command:---------\r\n");
    DebugSerial.write(Command);
    GprsSerail.write(Command);
    Time_Cont = 0;
    while (Time_Cont < Timeout)
    {
      gprsReadBuffer();
      if (strstr(gprsRxBuffer, Response) != NULL && strstr(gprsRxBuffer, Response2) != NULL)
      {
        DebugSerial.print("\r\n==========receive AT Command:==========\r\n");
        DebugSerial.print(gprsRxBuffer); //输出接收到的信息
        clrGprsRxBuffer();
        return Success;
      }
    }
    Time_Cont = 0;
  }
  DebugSerial.print("\r\n==========receive AT Command:==========\r\n");
  DebugSerial.print(gprsRxBuffer);//输出接收到的信息
  clrGprsRxBuffer();
  return Failure;
}
void Timer1_handler(void)
{
  Time_Cont++;
}
void gprsReadBuffer() {
  while (GprsSerail.available())
  {
    gprsRxBuffer[gprsBufferCount++] = GprsSerail.read();
    if (gprsBufferCount == gprsRxBufferLength)clrGprsRxBuffer();
  }
}
void clrGprsRxBuffer(void)
{
  memset(gprsRxBuffer, 0, gprsRxBufferLength);      //清空
  gprsBufferCount = 0;
}
/*****************************DHT11采集**********************************************/
void DHTData(){
      DHT11.read(DHT11PIN);
      delay(1);
      Temperature = DHT11.temperature;
      Humidity = DHT11.humidity;
}
/*****************************CO2采集**********************************************/
void CO2Data()
{
    volts = MGRead(MG_PIN);
    percentage = MGGetPercentage(volts,CO2Curve);
}
float MGRead(int mg_pin)
{
    int i;
    float v=0;
    for (i=0;i<READ_SAMPLE_TIMES;i++) {
        v += analogRead(mg_pin);
        delay(READ_SAMPLE_INTERVAL);
    }
    v = (v/READ_SAMPLE_TIMES) *5/1024 ;
    return v;  
} 
int  MGGetPercentage(float volts, float *pcurve)
{
   if ((volts/DC_GAIN )>=ZERO_POINT_VOLTAGE) {
      return -1;
   } else { 
      return pow(10, ((volts/DC_GAIN)-pcurve[1])/pcurve[2]+pcurve[0]);
   }
}
/***************************PM数据采集**************************************************/
void PMData()
{
  if(Serial2.find(0x42)){    //检测到0x42时，开始读取
    Serial2.readBytes(buf,LENG);
 
    if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module 
      }           
    } 
  }  
}
char checkValue(unsigned char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;
 
  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;
  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data 
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}
int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module  
  return PM10Val;
}
/***************************PM数据采集**************************************************/
void Smoke(){
smoke = analogRead(1);
}

